<template>
  <div class="app-container">
    <el-breadcrumb separator="/" class="breadcrumb">
      <el-breadcrumb-item :to="{ path: '/mycourse/courseList?ccid=' + ccid }">课程签到</el-breadcrumb-item>
      <el-breadcrumb-item :to="{ path: '/mycourse/signList?actId=' + actId }">签到活动</el-breadcrumb-item>

      <el-breadcrumb-item :to="{
        path: '/mycourse/signlinkList?actId=' + actId
      }">签到环节</el-breadcrumb-item>
      <el-breadcrumb-item>签到二维码</el-breadcrumb-item>
    </el-breadcrumb>
    <div class="result-container">
      <el-card shadow="never" style="margin-top: 15px">
        <el-row :gutter="20" style="
            align-items: center;
            padding-bottom: 10px;
            border-bottom: 0.5px solid #eee;
          ">
          <el-col :span="15">
            <span class="title">{{ courseName }}</span>
            <span class="className" style="margin-right: 15px; margin-left: 15px">
              名单:
              <el-tag type="warning">
                {{ className != 'undefined' ? className : '无' }}
              </el-tag>
            </span>
            <span class="linkType">
              签到环节: <el-tag>{{ linkType === 1 ? '签到' : '其他' }}</el-tag>
            </span>
          </el-col>
          <el-col :span="9" style="text-align: right">
            <span style="font-size: 23px; font-weight: bold; margin-right: 40px">
              签到人数：{{ signCount }}{{ classNum ? ' / ' + classNum : '' }}
            </span>
          </el-col>
        </el-row>
        <el-row :gutter="20">
          <el-col :span="10" style="height: 540px; padding-top: 30px">
            <!-- 根据签到状态显示不同内容 -->
            <div v-if="status === 2" class="sign-ended">
              <i class="el-icon-time" style="font-size: 48px; color: #909399;"></i>
              <p>签到已结束</p>
            </div>
            <div v-else>
              <div class="countdown" v-if="signStopType == 0">
                <span class="countdown-text">签到倒计时：</span>
                <span class="countdown-time">{{ countdownTime }}</span>
              </div>
              <div class="qrcode" ref="qrCodeUrl"></div>
            </div>
            <!-- <el-button
              class="share"
              @click="gotoShareCode()"
              size="small"
              type="primary"
              :disabled="status === 2"
              >生成二维码分享链接</el-button
            > -->
          </el-col>
          <el-col :span="14" style="padding-top: 20px">
            <el-tabs type="border-card" class="box-card" style="overflow-y: auto; overflow-x: hidden" ref="cardContent">
              <el-tab-pane label="已签到">
                  <div style="text-align: center; width: 80px; height: 120px; float: left;" v-for="item in listSign"
                    :key="item.name">
                    <el-avatar :size="50" :style="{ backgroundColor: getRandomColor(item.name) }">{{ item.name.slice(-2)
                    }}</el-avatar>
                    <div style="font-size: 12px; margin-top: 5px;">{{ item.studentId }}</div>
                  </div>
              </el-tab-pane>

              <el-tab-pane label="未签到">
                  <div style="text-align: center; width: 80px; height: 120px; float: left;" v-for="item in unsignlist"
                    :key="item.name">
                    <el-dropdown size="mini" style="cursor: pointer" @command="handleCommand2">
                      <el-avatar :size="50" :style="{ backgroundColor: getRandomColor(item.name) }">{{
                        item.name.slice(-2) }}</el-avatar>
                      <div style="font-size: 12px; margin-top: 5px;">{{ item.studentId }}</div>
                      <el-dropdown-menu slot="dropdown">
                        <el-dropdown-item :command="composeValue2('迟到', item.name)">迟到</el-dropdown-item>
                        <el-dropdown-item :command="composeValue2('请假', item.name)">请假</el-dropdown-item>
                        <el-dropdown-item :command="composeValue2('其他', item.name)">其他</el-dropdown-item>
                      </el-dropdown-menu>
                    </el-dropdown>
                  </div>
              </el-tab-pane>
            </el-tabs>
          </el-col>
        </el-row>
      </el-card>
    </div>
  </div>
</template>

<script>
import QRCode from 'qrcodejs2'
import Cookies from 'js-cookie'
var qrcode
export default {
  name: 'signcode',
  components: {
    //未使用
    // QRCode
  },
  data() {
    return {
      ccid: '',
      code: '',
      actId: '',
      lid: '',
      courseName: '',
      linkType: 1,
      className: '',
      timer: null,
      isEnd: false,
      screenWidth: 1920,
      isShow: true,
      peopleCnt: 0,
      path: 'wss://localhost:8001/ws/asset',
      socket: '',
      status: '1',
      unsignlist: [],
      listSign: [],  //存储接口返回的数据
      classNum: 0,
      totalnum: 0,
      signStopType: 0,
      signCount: 0,
      sharelink: '',
      circleUrl:
        'https://cube.elemeccdn.com/3/7c/3ea6beec64369c2642b92c6726f1epng.png',
      userColorMap: new Map(),
      countdownTime: '00:00',
      countdownTimer: null,
      endTime: '', // 结束时间
      randomnum: '',
      showRecoveryButton: true,
      heartbeatInterval: null, // 心跳检测定时器
      heartbeatTimeout: null, // 心跳超时定时器
      heartbeatIntervalTime: 30000, // 心跳检测间隔时间（毫秒）
      heartbeatTimeoutTime: 5000, // 心跳超时时间（毫秒）
    }
  },
  created() {
    this.screenWidth = document.body.clientWidth;
    this.screenHeight = document.body.clientHeight;
    this.status = this.$route.query.status;
    this.lid = window.sessionStorage.getItem('lid');
    this.ccid = window.sessionStorage.getItem('ccid');
    this.cid = window.sessionStorage.getItem('cid').toString();
    this.actId = window.sessionStorage.getItem('actId');
    this.courseName = window.sessionStorage.getItem('CourseName');
    this.signStopType = window.sessionStorage.getItem('signStopType');
    this.linkType = window.sessionStorage.getItem('linkType');
    this.className = window.sessionStorage.getItem('className');
    this.endTime = this.$route.query.EndTime;
    this.getUpdateCode();

    // 只在页面渲染完后再获取签到列表
    this.$nextTick(() => {
      this.getSignList();
      this.getunSignList();
    });

    this.getrandomnum();

    if (this.cid != '' && this.cid != 'undefined' && this.cid != null) { }
    this.status = parseInt(this.$route.query.status);


    if (this.signStopType == 0 && this.status === 1) {
      this.startCountdown();
    }
  },
  mounted() {
    this.creatQrCode()
    this.updateCode()
    this.init()
  },
  destroyed() {
    clearInterval(this.timer)
    if (this.countdownTimer) {
      clearInterval(this.countdownTimer)
    }
    if (window.sessionStorage.getItem('socketConnection') == 1) {
      this.close()
      window.sessionStorage.setItem('socketConnection', 0)
    }
    this.stopHeartbeat(); // 停止心跳检测
  },
  methods: {
    getRandomColor(userName) {
      if (this.userColorMap.has(userName)) {
        return this.userColorMap.get(userName);
      }

      const colors = ['#409EFF', '#67C23A', '#E6A23C', '#F56C6C', '#909399', '#9B59B6', '#3498DB', '#1ABC9C'];
      const randomColor = colors[Math.floor(Math.random() * colors.length)];
      this.userColorMap.set(userName, randomColor);
      return randomColor;
    },
    // 生成随机签到码
    async getrandomnum() {
      const { data: res } = await this.$http.get('/act/getCode', {
        params: {
          lid: this.lid
        }
      })
      if (res.code == 200) {
        this.randomnum = res.data
      }
      console.log('随机码=', this.randomnum)
    },
    // socket连接
    init: function () {
      if (typeof WebSocket === 'undefined') {
        alert('您的浏览器不支持socket')
      } else if (window.sessionStorage.getItem('socketConnection') == 0) {
        // 实例化socket
        this.socket = new WebSocket(this.path)
        // 监听socket连接
        this.socket.onopen = this.open
        // 监听socket错误信息
        this.socket.onerror = this.error
        // 监听socket消息
        this.socket.onmessage = this.getMessage
        // 监听socket关闭
        this.socket.onclose = this.close
      } else return
    },
    // 启动心跳检测
    startHeartbeat() {
      this.heartbeatInterval = setInterval(() => {
        if (this.socket && this.socket.readyState === WebSocket.OPEN) {
          this.socket.send('heartbeat');
          this.heartbeatTimeout = setTimeout(() => {
            this.reconnect();
          }, this.heartbeatTimeoutTime);
        }
      }, this.heartbeatIntervalTime);
    },
    // 停止心跳检测
    stopHeartbeat() {
      clearInterval(this.heartbeatInterval);
      clearTimeout(this.heartbeatTimeout);
    },
    // 重新连接
    reconnect() {
      this.stopHeartbeat();
      this.init();
    },
    // 获取签到列表
    async getSignList() {
      const { data: res } = await this.$http.get('rec/resultTeacher', {
        params: {
          lid: this.lid
        }
      })
      if (res.code == 200) {
        this.classNum = res.data[4] //返回班级人数
        this.className = res.data[3] || 'undefined'
        this.listSign = res.data[2].map(item => ({
          name: item.name, // 确保后端返回的数据中包含 name 属性
          studentId: item.student_id // 确保后端返回的数据中包含 id 属性
        }));//签到列表数据  同时包括姓名和学号吗？
        this.linkType = res.data[5]
        this.status = res.data[8]
        this.signStopType = res.data[6]
        this.signCount = this.listSign.length
      } else {
        this.signlist = []
        this.signnum = 0
      }
    },
    //获取未签到列表
    async getunSignList() {
      const { data: res } = await this.$http.get('rec/resultTeacher2', {
        params: {
          lid: this.lid
        }
      })
      if (res.code == 200) {
        this.unsignlist = res.data
        this.unsignnum = res.data.length
      } else {
        this.unsignlist = []
        this.unsignnum = 0
      }
    },

    open: function () {
      console.log('在code的socket连接成功')
      window.sessionStorage.setItem('socketConnection', 1)
      this.socket.send(window.sessionStorage.getItem('uid'))
      this.startHeartbeat(); // 启动心跳检测
    },
    error: function () { },
    getMessage: async function (msg) {
      console.log('code有人签到了！！！！！！！', msg)
      if (msg.data != '连接成功' && this.status !== 2) {
        const { data: res } = await this.$http.get('/act/startSignin', {
          params: {
            lid: this.lid
          }
        })
        if (res.code == 200) {
          this.getunSignList()
          this.listSign.unshift(JSON.parse(msg.data))
          this.signCount = this.listSign.length
        }
      }
    },
    close: function () {
      window.sessionStorage.setItem('socketConnection', 0)
      this.stopHeartbeat(); // 停止心跳检测
    },

    // 查询班级人数
    selectClassNum: async function () {
      const { data: res } = await this.$http.get('/class/selectClassNum', {
        params: {
          cid: this.cid
        }
      })
      if (res.code == 200) {
        this.classNum = res.data
      }
    },
    // 代签到
    async handleCommand2(command) {
      const { data: res } = await this.$http.get('/rec/recByTea2', {
        params: {
          lid: this.lid,
          name: command.name,
          state: command.state
        }
      })
      if (res.code == 200) {
        this.getSignList()
        this.getunSignList()
      }
    },
    updateCode() {
      var times = 0
      var that = this
      var i = setInterval(async function () {
        that.getSignList()
        that.getunSignList()
        that.signCount = that.listSign.length
        if (times == 0) {
          await that.getUpdateCode()
          qrcode.makeCode(that.code)
        }
        times = times + 2
        if (times == 10) {
          times = 0
        }
      }, 2000)
      this.timer = i
    },
    composeValue2(item, row) {
      return {
        state: item,
        name: row
      }
    },
    creatQrCode() {
        qrcode = new QRCode(this.$refs.qrCodeUrl, {
          text: this.code,
          image: '/src/assets/default_head_circle.png',
          width: this.screenWidth * 0.23,
          height: this.screenWidth * 0.23,
          colorDark: '#222',
          colorLight: 'white',
          correctLevel: QRCode.CorrectLevel.H
        });
        this.qrcode = qrcode;
    },
    // 实时获取二维码数据
    async getUpdateCode() {
      // 更新数据
      const { data: res } = await this.$http.get('/act/updateCode', {
        params: {
          lid: this.lid
        }
      })
      // 失败
      if (res.code != 200) {
        this.$message.error('获取信息失败')
        return false
      } else {
        this.code = res.data.code
      }
    },
    //前往分享链接地址
    // gotoShareCode() {
    //   if (this.status === '1' || this.signStopType == 1) {
    //     this.sharelink = `https://www.localhost/#/share?lid=${this.lid}&uid=${this.uid}&signStopType=${this.signStopType}`
    //     let oInput = document.createElement('input')
    //     oInput.value = this.sharelink
    //     document.body.appendChild(oInput)
    //     oInput.select() // 选择对象
    //     document.execCommand('Copy') // 执行浏览器复制命令
    //     oInput.className = 'oInput'
    //     oInput.style.display = 'none'
    //     this.$message.success('复制成功')
    //   } else {
    //     this.$alert('当前签到活动不在对应时间段', '提示', {
    //       confirmButtonText: '确定',
    //       callback: action => {
    //         this.$message({
    //           type: 'info',
    //           message: `分享失败`
    //         })
    //       }
    //     })
    //   }
    // },
    // //分享复制成功
    // onCopy(e) {
    //   this.$message({
    //     message: '复制成功',
    //     type: 'success'
    //   })
    // },
    // onError(e) {
    //   this.$message({
    //     message: '复制失败',
    //     type: 'error'
    //   })
    // },
    startCountdown() {
      // 获取当前时间和结束时间的时间戳（毫秒）
      const now = new Date().getTime();
      const endTime = new Date(this.endTime).getTime();
      console.log("endTime："+endTime)
      console.log("剩余时间：")
      console.log(endTime - now)
      // 如果结束时间与当前时间差大于一天，显示“无限时”
      if (endTime - now > 24 * 60 * 60 * 1000) {
        this.countdownTime = "无限时";
        return;
      }

      // 每秒钟更新一次倒计时
      this.countdownTimer = setInterval(() => {
        const remainingTime = endTime - new Date().getTime();

        // 如果时间到了，清除定时器并更新状态
        if (remainingTime <= 0) {
          clearInterval(this.countdownTimer);
          this.countdownTime = "00:00";
          this.handleSignEnd(); // 处理签到结束
        } else {
          // 格式化剩余时间为时:分:秒
          const minutes = Math.floor((remainingTime % (1000 * 60 * 60)) / (1000 * 60));
          const seconds = Math.floor((remainingTime % (1000 * 60)) / 1000);

          // 只有在时间更新时才更改倒计时文本
          this.countdownTime = `${this.formatTime(minutes)}:${this.formatTime(seconds)}`;
        }
      }, 1000); 
    },

    // 格式化时间，确保时间始终为两位数
    formatTime(time) {
      return time < 10 ? `0${time}` : time;
    },


    async handleSignEnd() {
      clearInterval(this.countdownTimer)
      this.status = 2 // 更新状态为已结束

      try {
        const { data: res } = await this.$http.get('/act/updateLinkStatus', {
          params: {
            lid: this.lid,
            status: 2,
            duration: this.$route.query.duration
          }
        })

        if (res.code === 200) {
          this.$message({
            type: 'warning',
            message: '签到时间已结束'
          })
        }
      } catch (error) {
        console.error('更新签到状态失败:', error)
      }
    },
  },
  beforeDestroy() {
    if (this.timer) {
      clearInterval(this.timer)
    }
    if (this.countdownTimer) {
      clearInterval(this.countdownTimer)
    }
  }
}
</script>




<style scoped>
.title,
.className,
.linkType {
  text-align: center;
}

.randomnum {
  text-align: center;
  margin: 10px 10px;
}

.title {
  color: #39b54a;
  font-size: 25px;
}

.className,
.linkType {
  margin: 10px 0px;
}

.qrcode {
  display: flex;
  justify-content: center;
  margin-top: 20px;
  margin-bottom: 10px;
}

.box-card {
  height: 500px;
}

/* 列表元素新增渐变 */
.v-enter,
.v-leave-to {
  opacity: 0;
}

.v-enter-active,
.v-leave-active {
  transition: all 1s ease;
}

.share {
  display: block;
  margin: 30px auto 0;
}

.sign-ended {
  display: flex;
  flex-direction: column;
  align-items: center;
  justify-content: center;
  height: 100%;
  color: #909399;
}

.sign-ended p {
  margin-top: 20px;
  font-size: 20px;
}

.countdown {
  text-align: center;
  margin-bottom: 20px;
}

.countdown-time {
  font-size: 24px;
  color: #409EFF;
  font-weight: bold;
}
</style>
